// The code below is an implementation of https://eprint.iacr.org/2020/351.pdf
// and uses
// https://gitlab.inria.fr/zk-curves/bw6-761/-/blob/master/sage/pairing.py and
// https://github.com/EYBlockchain/zk-swap-libff/tree/ey/libff/algebra/curves/bw6_761
// as references.

#include <libff/algebra/curves/bw6_761/bw6_761_g1.hpp>
#include <libff/algebra/curves/bw6_761/bw6_761_g2.hpp>
#include <libff/algebra/curves/bw6_761/bw6_761_init.hpp>

namespace libff
{

bigint<bw6_761_r_limbs> bw6_761_modulus_r;
bigint<bw6_761_q_limbs> bw6_761_modulus_q;

bw6_761_Fq bw6_761_coeff_b;
bw6_761_Fq bw6_761_twist;
bw6_761_Fq bw6_761_twist_coeff_b;

bigint<bw6_761_q_limbs> bw6_761_ate_loop_count1;
bigint<bw6_761_q_limbs> bw6_761_ate_loop_count2;
bool bw6_761_ate_is_loop_count_neg;
bigint<bw6_761_q_limbs> bw6_761_final_exponent_z;
bool bw6_761_final_exponent_is_z_neg;

void init_bw6_761_params()
{
    typedef bigint<bw6_761_r_limbs> bigint_r;
    typedef bigint<bw6_761_q_limbs> bigint_q;

    // Montgomery assumes this
    assert(sizeof(mp_limb_t) == 8 || sizeof(mp_limb_t) == 4);

    // Parameters for scalar field Fr
    // r =
    // 0x1ae3a4617c510eac63b05c06ca1493b1a22d9f300f5138f1ef3622fba094800170b5d44300000008508c00000000001
    bw6_761_modulus_r =
        bigint_r("2586644260129690940106527336948935335363935127549146605398842"
                 "62666720468348340822774968888139573360124440321458177");
    assert(bw6_761_Fr::modulus_is_valid());
    if (sizeof(mp_limb_t) == 8) {
        bw6_761_Fr::Rsquared = bigint_r(
            "661274283768726978163325701168662324052305289846649183196063154202"
            "33909940404532140033099444330447428417853902114");
        bw6_761_Fr::Rcubed = bigint_r(
            "157734475176213061358192738313701451942220138363611391489992831740"
            "412033225490229541667992423878570205050777755168");
        bw6_761_Fr::inv = 0x8508bfffffffffff;
    }
    if (sizeof(mp_limb_t) == 4) {
        bw6_761_Fr::Rsquared = bigint_r(
            "661274283768726978163325701168662324052305289846649183196063154202"
            "33909940404532140033099444330447428417853902114");
        bw6_761_Fr::Rcubed = bigint_r(
            "157734475176213061358192738313701451942220138363611391489992831740"
            "412033225490229541667992423878570205050777755168");
        bw6_761_Fr::inv = 0xffffffff;
    }
    bw6_761_Fr::num_bits = 377;
    bw6_761_Fr::euler =
        bigint_r("1293322130064845470053263668474467667681967563774573302699421"
                 "31333360234174170411387484444069786680062220160729088");
    bw6_761_Fr::s = 46;
    bw6_761_Fr::t =
        bigint_r("3675842578061421676390135839012792950148785745837396071634149"
                 "488243117337281387659330802195819009059");
    bw6_761_Fr::t_minus_1_over_2 =
        bigint_r("1837921289030710838195067919506396475074392872918698035817074"
                 "744121558668640693829665401097909504529");
    bw6_761_Fr::multiplicative_generator = bw6_761_Fr("15");
    bw6_761_Fr::root_of_unity =
        bw6_761_Fr("32863578547254505029601261939868325669770508939375122462904"
                   "745766352256812585773382134936404344547323199885654433");
    bw6_761_Fr::nqr = bw6_761_Fr("5");
    bw6_761_Fr::nqr_to_t =
        bw6_761_Fr("33774956008227656219775876656288133547078610493828613777258"
                   "829345740556592044969439504850374928261397247202212840");
    bw6_761_Fr::static_init();

    // Parameters for base field Fq
    // q =
    // 0x122e824fb83ce0ad187c94004faff3eb926186a81d14688528275ef8087be41707ba638e584e91903cebaff25b423048689c8ed12f9fd9071dcd3dc73ebff2e98a116c25667a8f8160cf8aeeaf0a437e6913e6870000082f49d00000000008b
    bw6_761_modulus_q =
        bigint_q("6891450384315732539396789682275657542479668912536150109513790"
                 "1602096234222434917360876831832894116876408645677537866134511"
                 "6175912055424775934951169912530159895160509937850885037254363"
                 "1423596795951899700429969112842764913119068299");
    assert(bw6_761_Fq::modulus_is_valid());
    if (sizeof(mp_limb_t) == 8) {
        bw6_761_Fq::Rsquared = bigint_q(
            "410173710550729835244256131339319232418037181415529408988358678008"
            "337131002543531210418765667118526087296627284304957029592342298086"
            "677137781899438438783090920915449892454598380340650741080836049574"
            "9428678951279422657716620863065");
        bw6_761_Fq::Rcubed = bigint_q(
            "297415514632118086526834853439131925910825545338380841392089322640"
            "624198677430665521626961318971291885148318712859327336480040754936"
            "765047304839676586453060891603903912680899124818868997690823101153"
            "644786484398736894438670450156");

        bw6_761_Fq::inv = 0xa5593568fa798dd;
    }
    if (sizeof(mp_limb_t) == 4) {
        bw6_761_Fq::Rsquared = bigint_q(
            "410173710550729835244256131339319232418037181415529408988358678008"
            "337131002543531210418765667118526087296627284304957029592342298086"
            "677137781899438438783090920915449892454598380340650741080836049574"
            "9428678951279422657716620863065");
        bw6_761_Fq::Rcubed = bigint_q(
            "297415514632118086526834853439131925910825545338380841392089322640"
            "624198677430665521626961318971291885148318712859327336480040754936"
            "765047304839676586453060891603903912680899124818868997690823101153"
            "644786484398736894438670450156");
        bw6_761_Fq::inv = 0x8fa798dd;
    }
    bw6_761_Fq::num_bits = 761;
    bw6_761_Fq::euler =
        bigint_q("3445725192157866269698394841137828771239834456268075054756895"
                 "0801048117111217458680438415916447058438204322838768933067255"
                 "8087956027712387967475584956265079947580254968925442518627181"
                 "5711798397975949850214984556421382456559534149");
    bw6_761_Fq::s = 1;
    bw6_761_Fq::t =
        bigint_q("3445725192157866269698394841137828771239834456268075054756895"
                 "0801048117111217458680438415916447058438204322838768933067255"
                 "8087956027712387967475584956265079947580254968925442518627181"
                 "5711798397975949850214984556421382456559534149");
    bw6_761_Fq::t_minus_1_over_2 =
        bigint_q("1722862596078933134849197420568914385619917228134037527378447"
                 "5400524058555608729340219207958223529219102161419384466533627"
                 "9043978013856193983737792478132539973790127484462721259313590"
                 "7855899198987974925107492278210691228279767074");
    bw6_761_Fq::multiplicative_generator = bw6_761_Fq("2");
    bw6_761_Fq::root_of_unity =
        bw6_761_Fq("68914503843157325393967896822756575424796689125361501095137"
                   "90160209623422243491736087683183289411687640864567753786613"
                   "45116175912055424775934951169912530159895160509937850885037"
                   "2543631423596795951899700429969112842764913119068298");
    bw6_761_Fq::nqr = bw6_761_Fq("2");
    bw6_761_Fq::nqr_to_t =
        bw6_761_Fq("68914503843157325393967896822756575424796689125361501095137"
                   "90160209623422243491736087683183289411687640864567753786613"
                   "45116175912055424775934951169912530159895160509937850885037"
                   "2543631423596795951899700429969112842764913119068298");
    bw6_761_Fq::static_init();

    // Parameters for Fq3
    bw6_761_Fq3::euler = bigint<3 * bw6_761_q_limbs>(
        "1636446854262954003249141699409548889559206196373633220512096143268984"
        "5397014880568641901171928604942518055908462554673180677727867910667998"
        "4663099143697116161447047621868304705520956489172590015220902479424161"
        "5633521368602921395669003930971333893630420619714613478078837246039873"
        "3124493326270446151854198371345979937646860351442184846671768256523932"
        "2945704382553665794724881767934477627356011124130848888786345848916593"
        "9567481576923242781572039862743001907835119097653682898829629358506603"
        "8893699793468601168791027807574316427084928535262789988925129164000203"
        "2048904566729137025370148302740362549750397891505412715221417910833483"
        "274288268810463328915955262815220574933205354950574767449");
    bw6_761_Fq3::s = 1;
    bw6_761_Fq3::t = bigint<3 * bw6_761_q_limbs>(
        "1636446854262954003249141699409548889559206196373633220512096143268984"
        "5397014880568641901171928604942518055908462554673180677727867910667998"
        "4663099143697116161447047621868304705520956489172590015220902479424161"
        "5633521368602921395669003930971333893630420619714613478078837246039873"
        "3124493326270446151854198371345979937646860351442184846671768256523932"
        "2945704382553665794724881767934477627356011124130848888786345848916593"
        "9567481576923242781572039862743001907835119097653682898829629358506603"
        "8893699793468601168791027807574316427084928535262789988925129164000203"
        "2048904566729137025370148302740362549750397891505412715221417910833483"
        "274288268810463328915955262815220574933205354950574767449");
    bw6_761_Fq3::t_minus_1_over_2 = bigint<3 * bw6_761_q_limbs>(
        "8182234271314770016245708497047744447796030981868166102560480716344922"
        "6985074402843209505859643024712590279542312773365903388639339553339992"
        "3315495718485580807235238109341523527604782445862950076104512397120807"
        "8167606843014606978345019654856669468152103098573067390394186230199366"
        "5622466631352230759270991856729899688234301757210924233358841282619661"
        "4728521912768328973624408839672388136780055620654244443931729244582969"
        "7837407884616213907860199313715009539175595488268414494148146792533019"
        "4468498967343005843955139037871582135424642676313949944625645820001016"
        "0244522833645685126850741513701812748751989457527063576107089554167416"
        "37144134405231664457977631407610287466602677475287383724");
    bw6_761_Fq3::nqr =
        bw6_761_Fq3(bw6_761_Fq("0"), bw6_761_Fq("1"), bw6_761_Fq("0"));
    bw6_761_Fq3::nqr_to_t = bw6_761_Fq3(
        bw6_761_Fq("68914503843157325393967896822756575424796689125361501095137"
                   "90160209623422243491736087683183289411687640864567753786613"
                   "45116175912055424775934951169912530159895160509937850885037"
                   "2543631423596795951899700429969112842764913119068298"),
        bw6_761_Fq("0"),
        bw6_761_Fq("0"));
    bw6_761_Fq3::non_residue =
        bw6_761_Fq("68914503843157325393967896822756575424796689125361501095137"
                   "90160209623422243491736087683183289411687640864567753786613"
                   "45116175912055424775934951169912530159895160509937850885037"
                   "2543631423596795951899700429969112842764913119068295");
    bw6_761_Fq3::nqr =
        bw6_761_Fq3(bw6_761_Fq("0"), bw6_761_Fq("1"), bw6_761_Fq("0"));
    bw6_761_Fq3::nqr_to_t = bw6_761_Fq3(
        bw6_761_Fq("68914503843157325393967896822756575424796689125361501095137"
                   "90160209623422243491736087683183289411687640864567753786613"
                   "45116175912055424775934951169912530159895160509937850885037"
                   "2543631423596795951899700429969112842764913119068298"),
        bw6_761_Fq("0"),
        bw6_761_Fq("0"));
    bw6_761_Fq3::Frobenius_coeffs_c1[0] = bw6_761_Fq("1");
    bw6_761_Fq3::Frobenius_coeffs_c1[1] =
        bw6_761_Fq("49224645602255232421181789425750803910820025302323243810630"
                   "48548642823052024664478336818169867474395270858391911405337"
                   "70724773573982666493944449046954210939153048282672820358254"
                   "9674992333383150446779312029624171857054392282775648");
    bw6_761_Fq3::Frobenius_coeffs_c1[2] =
        bw6_761_Fq("19689858240902092972786107397005771513976663823038257284507"
                   "41611566800370218827257750865013421937292370006175842381275"
                   "74391402338072758281990502122958319220742112227265030526782"
                   "2868639090213645505120388400344940985710520836292650");
    bw6_761_Fq3::Frobenius_coeffs_c2[0] = bw6_761_Fq("1");
    bw6_761_Fq3::Frobenius_coeffs_c2[1] =
        bw6_761_Fq("19689858240902092972786107397005771513976663823038257284507"
                   "41611566800370218827257750865013421937292370006175842381275"
                   "74391402338072758281990502122958319220742112227265030526782"
                   "2868639090213645505120388400344940985710520836292650");
    bw6_761_Fq3::Frobenius_coeffs_c2[2] =
        bw6_761_Fq("49224645602255232421181789425750803910820025302323243810630"
                   "48548642823052024664478336818169867474395270858391911405337"
                   "70724773573982666493944449046954210939153048282672820358254"
                   "9674992333383150446779312029624171857054392282775648");

    // Parameters for the field Fq^6
    bw6_761_Fq6::non_residue =
        bw6_761_Fq("68914503843157325393967896822756575424796689125361501095137"
                   "90160209623422243491736087683183289411687640864567753786613"
                   "45116175912055424775934951169912530159895160509937850885037"
                   "2543631423596795951899700429969112842764913119068295");
    bw6_761_Fq6::Frobenius_coeffs_c1[0] = bw6_761_Fq("1");
    bw6_761_Fq6::Frobenius_coeffs_c1[1] =
        bw6_761_Fq("49224645602255232421181789425750803910820025302323243810630"
                   "48548642823052024664478336818169867474395270858391911405337"
                   "70724773573982666493944449046954210939153048282672820358254"
                   "9674992333383150446779312029624171857054392282775649");
    bw6_761_Fq6::Frobenius_coeffs_c1[2] =
        bw6_761_Fq("49224645602255232421181789425750803910820025302323243810630"
                   "48548642823052024664478336818169867474395270858391911405337"
                   "70724773573982666493944449046954210939153048282672820358254"
                   "9674992333383150446779312029624171857054392282775648");
    bw6_761_Fq6::Frobenius_coeffs_c1[3] =
        bw6_761_Fq("68914503843157325393967896822756575424796689125361501095137"
                   "90160209623422243491736087683183289411687640864567753786613"
                   "45116175912055424775934951169912530159895160509937850885037"
                   "2543631423596795951899700429969112842764913119068298");
    bw6_761_Fq6::Frobenius_coeffs_c1[4] =
        bw6_761_Fq("19689858240902092972786107397005771513976663823038257284507"
                   "41611566800370218827257750865013421937292370006175842381275"
                   "74391402338072758281990502122958319220742112227265030526782"
                   "2868639090213645505120388400344940985710520836292650");
    bw6_761_Fq6::Frobenius_coeffs_c1[5] =
        bw6_761_Fq("19689858240902092972786107397005771513976663823038257284507"
                   "41611566800370218827257750865013421937292370006175842381275"
                   "74391402338072758281990502122958319220742112227265030526782"
                   "2868639090213645505120388400344940985710520836292651");

    bw6_761_Fq6::my_Fp2::non_residue = bw6_761_Fq3::non_residue;

    // Choice of short Weierstrass curve and its twist
    // E: y^2 = x^3 - 1
    // bw6_761_coeff_b = -1
    bw6_761_coeff_b =
        bw6_761_Fq("68914503843157325393967896822756575424796689125361501095137"
                   "90160209623422243491736087683183289411687640864567753786613"
                   "45116175912055424775934951169912530159895160509937850885037"
                   "2543631423596795951899700429969112842764913119068298");
    // E': y^2 = x^3 - 1 * (-4) = y^2 = x^3 + 4
    // bw6_761_twist = -4
    bw6_761_twist =
        bw6_761_Fq("68914503843157325393967896822756575424796689125361501095137"
                   "90160209623422243491736087683183289411687640864567753786613"
                   "45116175912055424775934951169912530159895160509937850885037"
                   "2543631423596795951899700429969112842764913119068295");
    // We use a M-twist here, hence:
    // bw6_761_twist_coeff_b = bw6_761_coeff_b * bw6_761_twist;
    bw6_761_twist_coeff_b = bw6_761_Fq("4");

    // Choice of group G1
    // Identities
    bw6_761_G1::G1_zero =
        bw6_761_G1(bw6_761_Fq::zero(), bw6_761_Fq::one(), bw6_761_Fq::zero());
    bw6_761_G1::G1_one = bw6_761_G1(
        bw6_761_Fq("62387722575946793680321456936228128387790058097608247331387"
                   "87810501188623461307351759238099287535516224314149266511977"
                   "13214082863595094002179048950761175436631780181109081136794"
                   "5064510304504157188661901055903167026722666149426237"),
        bw6_761_Fq("21017351265208974239115045622158349511481275559133679971627"
                   "89335052900271653517958562461315794228241561913734371411178"
                   "22693652768320387955309393418595047097184897208532179795812"
                   "4416462268292467002957525517188485984766314758624099"),
        bw6_761_Fq::one());

    // Curve coeffs
    bw6_761_G1::coeff_a = bw6_761_Fq::zero();
    bw6_761_G1::coeff_b = bw6_761_coeff_b;

    // Cofactor
    bw6_761_G1::h = bigint<bw6_761_G1::h_limbs>(
        "2664243587933581668398767770148807386775111827005265065594210250231297"
        "7592501693353047140953112195348280268661194876");

    // WNAF
    //
    // Below we use the same `wnaf_window_table` as used for alt_bn_128
    // TODO: Adjust the `wnaf_window_table` and `fixed_base_exp_window_table`
    bw6_761_G1::wnaf_window_table.resize(0);
    bw6_761_G1::wnaf_window_table.push_back(11);
    bw6_761_G1::wnaf_window_table.push_back(24);
    bw6_761_G1::wnaf_window_table.push_back(60);
    bw6_761_G1::wnaf_window_table.push_back(127);

    // Fixed-base exponentiation table
    bw6_761_G1::fixed_base_exp_window_table.resize(0);
    // window 1 is unbeaten in [-inf, 4.99]
    bw6_761_G1::fixed_base_exp_window_table.push_back(1);
    // window 2 is unbeaten in [4.99, 10.99]
    bw6_761_G1::fixed_base_exp_window_table.push_back(5);
    // window 3 is unbeaten in [10.99, 32.29]
    bw6_761_G1::fixed_base_exp_window_table.push_back(11);
    // window 4 is unbeaten in [32.29, 55.23]
    bw6_761_G1::fixed_base_exp_window_table.push_back(32);
    // window 5 is unbeaten in [55.23, 162.03]
    bw6_761_G1::fixed_base_exp_window_table.push_back(55);
    // window 6 is unbeaten in [162.03, 360.15]
    bw6_761_G1::fixed_base_exp_window_table.push_back(162);
    // window 7 is unbeaten in [360.15, 815.44]
    bw6_761_G1::fixed_base_exp_window_table.push_back(360);
    // window 8 is unbeaten in [815.44, 2373.07]
    bw6_761_G1::fixed_base_exp_window_table.push_back(815);
    // window 9 is unbeaten in [2373.07, 6977.75]
    bw6_761_G1::fixed_base_exp_window_table.push_back(2373);
    // window 10 is unbeaten in [6977.75, 7122.23]
    bw6_761_G1::fixed_base_exp_window_table.push_back(6978);
    // window 11 is unbeaten in [7122.23, 57818.46]
    bw6_761_G1::fixed_base_exp_window_table.push_back(7122);
    // window 12 is never the best
    bw6_761_G1::fixed_base_exp_window_table.push_back(0);
    // window 13 is unbeaten in [57818.46, 169679.14]
    bw6_761_G1::fixed_base_exp_window_table.push_back(57818);
    // window 14 is never the best
    bw6_761_G1::fixed_base_exp_window_table.push_back(0);
    // window 15 is unbeaten in [169679.14, 439758.91]
    bw6_761_G1::fixed_base_exp_window_table.push_back(169679);
    // window 16 is unbeaten in [439758.91, 936073.41]
    bw6_761_G1::fixed_base_exp_window_table.push_back(439759);
    // window 17 is unbeaten in [936073.41, 4666554.74]
    bw6_761_G1::fixed_base_exp_window_table.push_back(936073);
    // window 18 is never the best
    bw6_761_G1::fixed_base_exp_window_table.push_back(0);
    // window 19 is unbeaten in [4666554.74, 7580404.42]
    bw6_761_G1::fixed_base_exp_window_table.push_back(4666555);
    // window 20 is unbeaten in [7580404.42, 34552892.20]
    bw6_761_G1::fixed_base_exp_window_table.push_back(7580404);
    // window 21 is never the best
    bw6_761_G1::fixed_base_exp_window_table.push_back(0);
    // window 22 is unbeaten in [34552892.20, inf]
    bw6_761_G1::fixed_base_exp_window_table.push_back(34552892);

    // Choice of group G2
    // Identities
    bw6_761_G2::G2_zero =
        bw6_761_G2(bw6_761_Fq::zero(), bw6_761_Fq::one(), bw6_761_Fq::zero());
    bw6_761_G2::G2_one = bw6_761_G2(
        bw6_761_Fq("64453329105969793360358881527740716268988861397741013649339"
                   "48236926875073754470830732273879639675437155036544153105017"
                   "72959260056063167855429956276229474392791242909663615640117"
                   "1909259073181112518725201388196280039960074422214428"),
        bw6_761_Fq("56292365808953971938692216344454738775758653474108026394695"
                   "34015951552119346305989993003963171041825980447937581532149"
                   "72605680357108252243146746187917218885078195819486220416605"
                   "630144001533548163105316661692978285266378674355041"),
        bw6_761_Fq::one());

    // Curve coeffs
    bw6_761_G2::coeff_a = bw6_761_Fq::zero();
    bw6_761_G2::coeff_b = bw6_761_twist_coeff_b;

    // Cofactor
    bw6_761_G2::h = bigint<bw6_761_G2::h_limbs>(
        "2664243587933581668398767770148807386775111827005265065594210250231297"
        "7592501693353047140953112195348280268661194869");

    // wNAF window table
    bw6_761_G2::wnaf_window_table.resize(0);
    bw6_761_G2::wnaf_window_table.push_back(5);
    bw6_761_G2::wnaf_window_table.push_back(15);
    bw6_761_G2::wnaf_window_table.push_back(39);
    bw6_761_G2::wnaf_window_table.push_back(109);

    // Fixed-base exponentiation table
    bw6_761_G2::fixed_base_exp_window_table.resize(0);
    // window 1 is unbeaten in [-inf, 5.10]
    bw6_761_G2::fixed_base_exp_window_table.push_back(1);
    // window 2 is unbeaten in [5.10, 10.43]
    bw6_761_G2::fixed_base_exp_window_table.push_back(5);
    // window 3 is unbeaten in [10.43, 25.28]
    bw6_761_G2::fixed_base_exp_window_table.push_back(10);
    // window 4 is unbeaten in [25.28, 59.00]
    bw6_761_G2::fixed_base_exp_window_table.push_back(25);
    // window 5 is unbeaten in [59.00, 154.03]
    bw6_761_G2::fixed_base_exp_window_table.push_back(59);
    // window 6 is unbeaten in [154.03, 334.25]
    bw6_761_G2::fixed_base_exp_window_table.push_back(154);
    // window 7 is unbeaten in [334.25, 742.58]
    bw6_761_G2::fixed_base_exp_window_table.push_back(334);
    // window 8 is unbeaten in [742.58, 2034.40]
    bw6_761_G2::fixed_base_exp_window_table.push_back(743);
    // window 9 is unbeaten in [2034.40, 4987.56]
    bw6_761_G2::fixed_base_exp_window_table.push_back(2034);
    // window 10 is unbeaten in [4987.56, 8888.27]
    bw6_761_G2::fixed_base_exp_window_table.push_back(4988);
    // window 11 is unbeaten in [8888.27, 26271.13]
    bw6_761_G2::fixed_base_exp_window_table.push_back(8888);
    // window 12 is unbeaten in [26271.13, 39768.20]
    bw6_761_G2::fixed_base_exp_window_table.push_back(26271);
    // window 13 is unbeaten in [39768.20, 106275.75]
    bw6_761_G2::fixed_base_exp_window_table.push_back(39768);
    // window 14 is unbeaten in [106275.75, 141703.40]
    bw6_761_G2::fixed_base_exp_window_table.push_back(106276);
    // window 15 is unbeaten in [141703.40, 462422.97]
    bw6_761_G2::fixed_base_exp_window_table.push_back(141703);
    // window 16 is unbeaten in [462422.97, 926871.84]
    bw6_761_G2::fixed_base_exp_window_table.push_back(462423);
    // window 17 is unbeaten in [926871.84, 4873049.17]
    bw6_761_G2::fixed_base_exp_window_table.push_back(926872);
    // window 18 is never the best
    bw6_761_G2::fixed_base_exp_window_table.push_back(0);
    // window 19 is unbeaten in [4873049.17, 5706707.88]
    bw6_761_G2::fixed_base_exp_window_table.push_back(4873049);
    // window 20 is unbeaten in [5706707.88, 31673814.95]
    bw6_761_G2::fixed_base_exp_window_table.push_back(5706708);
    // window 21 is never the best
    bw6_761_G2::fixed_base_exp_window_table.push_back(0);
    // window 22 is unbeaten in [31673814.95, inf]
    bw6_761_G2::fixed_base_exp_window_table.push_back(31673815);

    // Pairing parameters
    // See Algorithm 5 for Miller Loop: https://eprint.iacr.org/2020/351.pdf
    // ate_opt(P,Q) = (f_{u^3-u^2-u,Q}(P)f^{q}_{u+1,Q}(P))^(q^6 - 1)/r
    //
    // u+1
    bw6_761_ate_loop_count1 = bigint_q("9586122913090633730");
    // u^3-u^2-u
    bw6_761_ate_loop_count2 =
        bigint_q("880904806456922042166256752416502360955572640081583800319");
    bw6_761_ate_is_loop_count_neg = false;
    // u
    bw6_761_final_exponent_z = bigint_q("9586122913090633729");
    bw6_761_final_exponent_is_z_neg = false;
}

} // namespace libff
